package cn.xzqwjw.taskmanager.utils;

import cn.hutool.core.map.MapUtil;
import cn.xzqwjw.taskmanager.common.exception.CustomException;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.xzqwjw.taskmanager.common.customEnum.ResponseCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author wjw
 */
@Slf4j
public class CommonUtil {

  /**
   * 检测对象是否为空值
   * Java中可变长参数的使用及注意事项
   * <a href="https://www.cnblogs.com/lanxuezaipiao/p/3190673.html">...</a>
   */
  public static void checkNull(Object... objs) {
    if (Objects.isNull(objs) || objs.length == 0) {
      throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
    }
    for (Object obj : objs) {
      if (obj instanceof String) {
        if (!StringUtils.hasText(obj.toString())) {
          throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
        }
      }
      if (obj instanceof Collection) {
        if (CollectionUtils.isEmpty((Collection<?>) obj)) {
          throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
        }
      }
      if (obj instanceof Map) {
        if (MapUtil.isEmpty((Map<?, ?>) obj)) {
          throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
        }
      }
    }
  }

  /**
   * 检查传入的参数id是否大于0，id 为 String
   */
  public static void checkId(String idString) {
    if (!StringUtils.hasText(idString)) {
      throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
    }
    if (ConvertUtil.isWrongLongString(idString)) {
      throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
    }
    if (Long.parseLong(idString) <= 0L) {
      throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
    }
  }

  /**
   * 检查传入的参数id是否大于0，id 为 Integer
   */
  public static void checkId(Integer idInteger) {
    if (Objects.isNull(idInteger) || idInteger <= 0) {
      throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
    }
  }

  /**
   * 检查传入的参数id是否大于0，id 为 Long
   */
  public static void checkId(Long idLong) {
    if (Objects.isNull(idLong) || idLong <= 0) {
      throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
    }
  }

  /**
   * 检查传入的多个参数id是否大于0，id 为多个Integer类型的id
   */
  public static void checkId(Object... ids) {
    for (Object idObj : ids) {
      if (Objects.isNull(idObj)) {
        throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
      }
      if (idObj instanceof Integer) {
        if ((int) idObj <= 0) {
          throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
        }
      }
      if (idObj instanceof Long) {
        if ((long) idObj <= 0) {
          throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
        }
      }
    }
  }

  /**
   * 检查传入的ids里每个id是否大于0，ids为3,4,5格式
   */
  public static void checkIds(String ids) {
    // 检查是否为空
    if (!StringUtils.hasText(ids)) {
      throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
    }
    String[] aryIds = ids.split(",");
    for (String idString : aryIds) {
      try {
        if (Integer.parseInt(idString) <= 0) {
          throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
        }
      } catch (NumberFormatException e) {
        throw new CustomException(ResponseCodeEnum.BAD_REQUEST);
      }
    }
  }

  // ==================== 其他常用功能 ====================

  public static Page<Map<String, Object>> getPage(Integer pageCurrent, Integer pageSize) {
    CommonUtil.checkNull(pageCurrent, pageSize);
    return new Page<>(pageCurrent, pageSize);
  }

  /**
   * 计算分页总页数
   */
  public static Integer getPageCount(Long recordCount, Integer pageSize) {
    int pageCount = (int) (Math.ceil((double) recordCount / (double) pageSize));
    pageCount = pageCount == 0 ? 1 : pageCount;
    return pageCount;
  }

  /**
   * Integer 重载，如果一个表中有 id, flag_xxx 字段，设置开关此字段值的 UpdateWrapper
   */
  public static <T> UpdateWrapper<T> setToggleWrapper(String columnName, Integer id, Boolean flagValue) {
    UpdateWrapper<T> wrapper = new UpdateWrapper<>();
    wrapper.set(columnName, !flagValue).eq("id", id);
    return wrapper;
  }

  /**
   * Long 重载，如果一个表中有 id, flag_xxx 字段，设置开关此字段值的 UpdateWrapper
   */
  public static <T> UpdateWrapper<T> setToggleWrapper(String columnName, Long id, Boolean flagValue) {
    UpdateWrapper<T> wrapper = new UpdateWrapper<>();
    wrapper.set(columnName, !flagValue).eq("id", id);
    return wrapper;
  }

  /**
   * 添加包含 label、code、username 字段的对象时，经常要验证这两个字段是否已经添加，因此做一个通用的判断函数
   *
   * @param resultMap 从数据库查询出来的map对象
   *                  必须选择id字段，使用 wrapper.select("id").eq("label", label) 查询值;
   * @return 数据库中已经有值则返回true，否则返回false
   */
  public static boolean hasAdded(Map<String, Object> resultMap) {
    if (CollectionUtils.isEmpty(resultMap)) {
      return false;
    } else if (Objects.isNull(resultMap.get("id"))) {
      return false;
    } else {
      return (int) resultMap.get("id") > 0;
    }
  }

}
